﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Bot.Domain;
using Google.Cloud.Dialogflow.V2;
using Castle.MicroKernel.Facilities;
using Castle.MicroKernel;
using Newtonsoft.Json;
using Bot.Domain.Interfaces;

namespace Bot.Domain.DialogFlow.Convertor
{
    public class IntentConvertor : IIntentConvertor
    {
        private IEntityDomainService _entityDomainService;
        public IntentConvertor(IEntityDomainService entityDomainService)
        {
            _entityDomainService = entityDomainService;
        }

        public void Convert(IntentDto dto, Google.Cloud.Dialogflow.V2.Intent result)
        {
            //Base data
            //result.IntentName = null;
            result.Action = string.Empty;
            result.DisplayName = dto.Name;
            result.MlDisabled = false;
            result.IsFallback = false;
            result.ParentFollowupIntentName = "";
            result.Priority = 500000;
            result.RootFollowupIntentName = "";
            string eventName = Utils.CreateMD5Hash(dto.Name);
            result.Events.Add(eventName);
            result.WebhookState = Google.Cloud.Dialogflow.V2.Intent.Types.WebhookState.Unspecified;
            result.ResetContexts = false;
            //convert TrainingPhrases
            List<Google.Cloud.Dialogflow.V2.Intent.Types.Parameter> paramLst = new List<Google.Cloud.Dialogflow.V2.Intent.Types.Parameter>();
            foreach (var question in dto.Questions)
            {
                var phrase = new Google.Cloud.Dialogflow.V2.Intent.Types.TrainingPhrase() { Type = Google.Cloud.Dialogflow.V2.Intent.Types.TrainingPhrase.Types.Type.Example };
                if (question.QuestionEntities != null && question.QuestionEntities.Count > 0)
                {
                    int start = 0;
                    foreach (var part in question.QuestionEntities.OrderBy(n => n.StartPos))
                    {
                        if (part.StartPos > start)
                        {
                            phrase.Parts.Add(new Google.Cloud.Dialogflow.V2.Intent.Types.TrainingPhrase.Types.Part()
                            {
                                Text = question.Question.Substring(start, part.StartPos - start)
                            });
                        }
                        var entity = _entityDomainService.Get(part.EntityId);
                        if (entity != null)
                        {
                            string entityType = "";
                            if (entity.Type == Enum.EnumEntityType.systemEntity 
                                //&& !string.IsNullOrEmpty(entity.MappingToDialogflowId)
                                )
                            {
                                entityType = entity.Name;
                            }
                            if (entity.Type == Enum.EnumEntityType.entity)
                            {
                                entityType = string.Format("@{0}", entity.Name);
                            }
                            if (!string.IsNullOrEmpty(part.EntityLabel))
                            {
                                phrase.Parts.Add(new Google.Cloud.Dialogflow.V2.Intent.Types.TrainingPhrase.Types.Part()
                                {
                                    Text = question.Question.Substring(part.StartPos, part.EndPos - part.StartPos + 1),
                                    EntityType = entityType,
                                    Alias = part.EntityLabel,
                                    UserDefined = true
                                });
                                //update parameter
                                if (paramLst.Count <= 0 || paramLst.FirstOrDefault(p => p.DisplayName == part.EntityLabel) == null)
                                {
                                    var newPara = new Google.Cloud.Dialogflow.V2.Intent.Types.Parameter()
                                    {
                                        DisplayName = part.EntityLabel,
                                        EntityTypeDisplayName = entityType,
                                        Value = "$" + part.EntityLabel
                                    };
                                    //if (dto.EntityCollectionPrompts != null && dto.EntityCollectionPrompts.Count > 0)
                                    //{
                                    //    var promptsDtos = dto.EntityCollectionPrompts.Where(w => w.EntityLabel.Equals(part.EntityLabel));
                                    //    if (promptsDtos != null && promptsDtos.Count() > 0)
                                    //    {
                                    //        EntityCollectionPromptsDto entityCollectionDto = promptsDtos.FirstOrDefault();
                                    //        //dto.Intent.CollectionType==2 presents via prompts
                                    //        if (entityCollectionDto != null && dto.EntityCollectionType == EnumEntityCollectionType.prompt)
                                    //        {
                                    //            newPara.Mandatory = true;
                                    //            foreach (var item in entityCollectionDto.Questions)
                                    //            {
                                    //                newPara.Prompts.Add(item);
                                    //            }
                                    //        }
                                    //    }
                                    //}
                                    paramLst.Add(newPara);
                                    //result.Parameters.Add(newPara);
                                }
                            }
                            else
                            {
                                phrase.Parts.Add(new Google.Cloud.Dialogflow.V2.Intent.Types.TrainingPhrase.Types.Part()
                                {
                                    Text = question.Question.Substring(part.StartPos, part.EndPos - part.StartPos + 1)
                                });
                            }
                        }
                        else
                        {
                            phrase.Parts.Add(new Google.Cloud.Dialogflow.V2.Intent.Types.TrainingPhrase.Types.Part()
                            {
                                Text = question.Question.Substring(part.StartPos, part.EndPos - part.StartPos + 1)
                            });
                        }
                        start = part.EndPos + 1;
                    }
                    if (question.Question.Length > start)
                    {
                        phrase.Parts.Add(new Google.Cloud.Dialogflow.V2.Intent.Types.TrainingPhrase.Types.Part()
                        {
                            Text = question.Question.Substring(start, question.Question.Length - start)
                        });
                    }
                }
                else
                {
                    phrase.Parts.Add(new Google.Cloud.Dialogflow.V2.Intent.Types.TrainingPhrase.Types.Part()
                    {
                        Text = question.Question
                    });
                }
                result.TrainingPhrases.Add(phrase);
            }
            //对含有prompts的parameter进行排序,按照EntityCollectionPrompts的顺序
            List<Google.Cloud.Dialogflow.V2.Intent.Types.Parameter> orderedParamWithPrompts = new List<Google.Cloud.Dialogflow.V2.Intent.Types.Parameter>();
            //if (dto.EntityCollectionPrompts != null && dto.EntityCollectionPrompts.Count > 0)
            //{
            //    foreach (var item in dto.EntityCollectionPrompts)
            //    {
            //        foreach (var para in paramLst)
            //        {
            //            if (item.EntityLabel == para.DisplayName)
            //            {
            //                orderedParamWithPrompts.Add(para);
            //                break;
            //            }
            //        }
            //    }
            //}
            if (orderedParamWithPrompts.Count > 0)
            {
                result.Parameters.AddRange(orderedParamWithPrompts);
                foreach (var item in paramLst)
                {
                    if (orderedParamWithPrompts.Any(a => a.DisplayName == item.DisplayName)) continue;
                    result.Parameters.Add(item);
                }
            }
            else
            {
                result.Parameters.AddRange(paramLst);
            }

            var settings = new JsonSerializerSettings
            {
                ContractResolver = new Newtonsoft.Json.Serialization.CamelCasePropertyNamesContractResolver(),
                Formatting = Formatting.Indented,
                NullValueHandling = NullValueHandling.Ignore
            };
            LogHelper.Debug(string.Format("intent json for dialogflow: {0}", JsonConvert.SerializeObject(result, settings)));
            //convert contexts
            //result.InputContextNames, result.OutputContexts
            //convert event
            //result.Events
        }
    }
}
